/**
 * 
 */
package com.maywide.jdp.system.aspect;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.maywide.jdp.system.bean.BusinessFunctionBean;
import com.maywide.jdp.system.bean.RoleBean;
import com.maywide.jdp.system.bean.RuleBean;
import com.maywide.jdp.system.entities.BusinessFunction;
import com.maywide.jdp.system.entities.Module;
import com.maywide.jdp.system.entities.Role;
import com.maywide.jdp.system.entities.Rule;
import com.maywide.jdp.system.service.BusinessFunctionServiceImpl;

/**
 * @author luoyang
 */
@Aspect
@Component("businessFunctionAspect")
public class BusinessFunctionAspect {
	private Cache<String, Object> cache = null;
	
	private BusinessFunctionBean businessFunctionBean = null;
	private RoleBean roleBean = null;
	private RuleBean ruleBean = null;
	
	@Resource(name = "cache")
	public void setCache(Cache<String, Object> cache) {
		this.cache = cache;
	}

	@Resource(name = "businessFunctionBean")
	public void setBusinessFunctionBean(BusinessFunctionBean businessFunctionBean) {
		this.businessFunctionBean = businessFunctionBean;
	}

	@Resource(name = "roleBean")
	public void setRoleBean(RoleBean roleBean) {
		this.roleBean = roleBean;
	}

	@Resource(name = "ruleBean")
	public void setRuleBean(RuleBean ruleBean) {
		this.ruleBean = ruleBean;
	}

	@SuppressWarnings("unused")
	@Order(100)
	@AfterReturning(pointcut="execution(public * com.maywide.jdp.system.service.BusinessFunctionService.insert(..))",returning="retVal")
	private void doInsert(Object retVal) throws Exception {
		BusinessFunction businessFunction = (BusinessFunction) retVal;
		List<Role> roles = businessFunction.getRoles();
		List<Rule> rules = businessFunction.getRules();
		if(rules != null || roles != null) {
			if(rules != null) {
				String path = new StringBuffer("/rules/").append(businessFunction.getModule().getBeanName()).append("/").append(businessFunction.getServerClass()).append(".").append(businessFunction.getServerFunction()).toString();
				for(Rule rule : rules) {
					cache.put(path, rule.getId(), rule);
				}
			}
			if(roles != null) {
				String path = new StringBuffer("/roles/").append("/").append(businessFunction.getServerClass()).append(".").append(businessFunction.getServerFunction()).toString();
				for(Role role : roles) {
					cache.put(path, role.getId(), role);
				}
			}
		}
	}

	@SuppressWarnings({ "unused", "rawtypes" })
	@Order(100)
	@AfterReturning(pointcut="execution(public * com.maywide.jdp.system.service.BusinessFunctionService.update(..)) and args(businessFunctionVO,..)",returning="retVal",argNames="retVal,businessFunctionVO")
	private void doUpdate(Object retVal,BusinessFunction businessFunctionVO) throws Exception {
		BusinessFunction ret = (BusinessFunction) retVal;
		BusinessFunction old = (BusinessFunction)businessFunctionBean.load(ret.getId());
		Module module = old.getModule();
		
		List<Rule> rules = businessFunctionVO.getRules();
		List<Role> roles = businessFunctionVO.getRoles();
		
		String oldRoleClass = new StringBuffer("/roles/").append(old.getServerClass()).append(".").append(old.getServerFunction()).toString();
		String newRoleClass = new StringBuffer("/roles/").append(businessFunctionVO.getServerClass()).append(".").append(businessFunctionVO.getServerFunction()).toString();
		String oldRuleClass = new StringBuffer("/rules/").append(module.getBeanName()).append("/").append(old.getServerClass()).append(".").append(old.getServerFunction()).toString();
		String newRuleClass = new StringBuffer("/rules/").append(module.getBeanName()).append("/").append(businessFunctionVO.getServerClass()).append(".").append(businessFunctionVO.getServerFunction()).toString();
		
		cache.clearData(oldRoleClass);
		if(roles != null) {
			for(Role role : roles) {
				String roleID = role.getId();
				cache.put(oldRoleClass, roleID,(Role)roleBean.load(roleID));
			}
		}
		if(!oldRoleClass.equals(newRoleClass)) {
			Fqn fqn = Fqn.fromString(oldRoleClass);
			Map<String, Object> data = cache.getData(fqn);
			cache.put(newRoleClass, data);
			cache.removeNode(oldRoleClass);
		}

		String path = oldRuleClass;
		if(!oldRuleClass.equals(newRuleClass)) {
			cache.removeNode(oldRuleClass);
			path = newRoleClass;
		}
		cache.clearData(path);
		if(rules != null) {
			for(Rule rule : rules) {
				String ruleID = rule.getId();
				cache.put(path, ruleID, (Rule)ruleBean.load(ruleID));
			}
		}
	}

	@SuppressWarnings({ "unused", "rawtypes" })
	@Order(100)
	@AfterReturning(pointcut="execution(public * com.maywide.jdp.system.service.BusinessFunctionService.updateApp(..)) and args(businessFunctionVO,appType,..)",returning="retVal",argNames="retVal,businessFunctionVO,appType")
	private void doUpdateApp(Object retVal,BusinessFunction businessFunctionVO,String appType) throws Exception {
		BusinessFunction ret = (BusinessFunction) retVal;
		BusinessFunction old = (BusinessFunction)businessFunctionBean.load(ret.getId());
		Module module = old.getModule();
		List<Rule> rules = businessFunctionVO.getRules();
		List<Role> roles = businessFunctionVO.getRoles();
		
		String oldRoleClass = new StringBuffer("/roles/").append(old.getServerClass()).append(".").append(old.getServerFunction()).toString();
		String newRoleClass = new StringBuffer("/roles/").append(businessFunctionVO.getServerClass()).append(".").append(businessFunctionVO.getServerFunction()).toString();
		String oldRuleClass = new StringBuffer("/rules/").append(module.getBeanName()).append("/").append(old.getServerClass()).append(".").append(old.getServerFunction()).toString();
		String newRuleClass = new StringBuffer("/rules/").append(module.getBeanName()).append("/").append(businessFunctionVO.getServerClass()).append(".").append(businessFunctionVO.getServerFunction()).toString();
		
		cache.clearData(oldRoleClass);
		if(roles != null && appType.equals(BusinessFunctionServiceImpl.APP_TYPE_ROLES)) {
			for(Role role : roles) {
				String roleID = role.getId();
				cache.put(oldRoleClass, roleID,(Role)roleBean.load(roleID));
			}
		}
		if(!oldRoleClass.equals(newRoleClass) && appType.equals(BusinessFunctionServiceImpl.APP_TYPE_BASE)) {
			Fqn fqn = Fqn.fromString(oldRoleClass);
			Map<String, Object> data = cache.getData(fqn);
			cache.put(newRoleClass, data);
			cache.removeNode(oldRoleClass);
		}
	
		if(rules != null && appType.equals(BusinessFunctionServiceImpl.APP_TYPE_RULES)) {
			cache.clearData(oldRuleClass);
			for(Rule rule : rules) {
				String ruleID = rule.getId();
				cache.put(oldRuleClass, ruleID, (Rule)ruleBean.load(ruleID));
			}
		}
		if(!oldRuleClass.equals(newRuleClass) && appType.equals(BusinessFunctionServiceImpl.APP_TYPE_BASE)) {
			Fqn fqn = Fqn.fromString(oldRuleClass);
			Map<String, Object> data = cache.getData(fqn);
			cache.put(newRuleClass, data);
			cache.removeNode(oldRuleClass);
		}
	}
}
